home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Night Owl 8
/
Night Owl CD-ROM (NOPV8) (Night Owl Publisher) (1993).ISO
/
047a
/
lex_yacc.arj
/
EXPR.Y
< prev
next >
Wrap
Text File
|
1989-05-28
|
2KB
|
76 lines
/* Sample Yacc specification for simple desktop calculator; derived
from a specification in Aho et al: Compilers. Principles, Techniques
and Tools (sect. 4.9).
Lexical analyzer is described by Lex specification in exprlex.l.
To compile parser and lexical analyzer, issue the following commands:
yacc expr
lex exprlex
tpc expr
If you want to trace the actions executed by the parser, compile expr.pas
with the command:
tpc expr /Dyydebug
(In this case, it may be useful to refer to the parser description generated
by Yacc (file expr.lst).)
Description: This program reads simple arithmetic expressions, constructed
with real numbers, operators +, -, *, /, unary - and parentheses (operators
have their usual precedence, unary minus is highest), from standard input
(one per line) and prints the result on standard output.
Variables are denoted by a single letter (no distinction between upper and
lowercase letters); they are assigned values through an assignment of the
form <var>=<expr>.
To terminate the program, type ^Z or a period `.' at the beginning of a
line. */
%{
uses LexLib, YaccLib;
{$I exprlex} { lexical analyser }
var var_table : array [1..26] of real;
{ variable table, initialized to zeros }
%}
%union {
number : real;
variable : integer;
}
%token <number> NUMBER /* real constants */
%token <variable> VARIABLE /* single letter variable */
%type <number> expr /* real-valued expressions */
%left '+' '-' /* operators */
%left '*' '/'
%right UMINUS
%token EOF /* . at the beginning of a line */
%token ILLEGAL /* illegal token */
%%
input : /* empty */
| input '\n' /* empty line */
| input expr '\n' { writeln($2) }
| input VARIABLE '=' expr '\n'
{ var_table[$2] := $4 }
| input EOF { yyaccept }
| error '\n' { write('reenter last line: '); yyerrok }
;
expr : expr '+' expr { $$ := $1 + $3 }
| expr '-' expr { $$ := $1 - $3 }
| expr '*' expr { $$ := $1 * $3 }
| expr '/' expr { $$ := $1 / $3 }
| '(' expr ')' { $$ := $2 }
| '-' expr %prec UMINUS { $$ := -$2 }
| NUMBER { $$ := $1 }
| VARIABLE { $$ := var_table[$1] }
;
%%
var i : integer;
begin
for i := 1 to 26 do var_table[i] := 0.0;
if yyparse=0 then { done }
end.